package com.jinglephone.sdk;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.SimpleAdapter;

import org.pjsip.pjsua2.AccountConfig;
import org.pjsip.pjsua2.AccountRegConfig;
import org.pjsip.pjsua2.AuthCredInfo;
import org.pjsip.pjsua2.AuthCredInfoVector;
import org.pjsip.pjsua2.CallInfo;
import org.pjsip.pjsua2.CallMediaInfoVector;
import org.pjsip.pjsua2.CallOpParam;
import org.pjsip.pjsua2.CallSetting;
import org.pjsip.pjsua2.MediaConfig;
import org.pjsip.pjsua2.StreamInfo;
import org.pjsip.pjsua2.app.JinglePhoneDef;
import org.pjsip.pjsua2.app.MyAccount;
import org.pjsip.pjsua2.app.MyAppObserver;
import org.pjsip.pjsua2.app.MyBuddy;
import org.pjsip.pjsua2.app.MyCall;
import org.pjsip.pjsua2.app.PjSua2;
import org.pjsip.pjsua2.pjsip_inv_state;
import org.pjsip.pjsua2.pjsip_status_code;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * JingLePhone SIP接口实例
 *
 * @author wx
 * @date 2016.06.13
 */
public class JinglePhone implements IJingLePhone, Handler.Callback, MyAppObserver {

    private static String TAG = "JingLePhone";
    private static String SIP = "sip:";
    private static String AT = "@";
    //回调函数
    private Context mContext = null;
    private ISipCallBack mCallBack = null;
    private RegisterParam mRegisterParam = null;
    private SipOption mSipOption = null;
    private SimpleAdapter mBuddyListAdapter;
    private static PjSua2 mPjSua2 = null;
    private static MyAccount mAccount = null;
    private static AccountConfig mAccCfg = null;
    private static MediaConfig mMeCfg = null;
    private static CallSetting mCs = null;
    private static ArrayList<Map<String, String>> mBuddyList = null;
    private static HashMap<String, MyCall> mCallMap = new HashMap<String, MyCall>();
    private final Handler handler = new Handler(this);
    private String mRegisterStates = "";
    private String mRegisterSequential = "";
    private int mAnswerCheckCount = 0;
    private String mNumber = null;
    private String mCallState = "";
    private class MSG_TYPE {
        public final static int INCOMING_CALL = 1;
        public final static int CALL_STATE = 2;
        public final static int REG_STATE = 3;
        public final static int BUDDY_STATE = 4;
        public final static int CALL_MEDIA_STATE = 5;
        public final static int REGISTER_START = 6;
        public final static int TDMF_STATE = 7;
        public final static int TIMEOUT = 8;
        public final static int HANGUP = 9;
        public final static int REG_STATE_END = 10;
    }
    @Override
    public void notifyDTMFState(String dtmf) {
        Message m = Message.obtain(handler, MSG_TYPE.TDMF_STATE, dtmf);
        m.sendToTarget();
    }
    @Override
    public void notifyRegState(pjsip_status_code code, String reason, int expiration) {
        String msg_str = "";
        String registrStates = "";
        if (expiration == 0)
            msg_str += "Unregistration";
        else
            msg_str += "Registration";

        if (code.swigValue() / 100 == 2) {
            msg_str += " successful";
            registrStates = SipConst.REG_STATE_COMPLETE;
        }else {
            msg_str += " failed: " + reason;
            registrStates = SipConst.REG_STATE_END;
        }
        Log.d(TAG, "msg_str = " + msg_str);
        if(!mRegisterStates.equals(registrStates)) {
            mRegisterStates = registrStates;
            if(mRegisterStates.equals(SipConst.REG_STATE_COMPLETE)) {
                Message m = Message.obtain(handler, MSG_TYPE.REG_STATE,registrStates);
                m.sendToTarget();
            }
            if(registrStates.equals(SipConst.REG_STATE_END)){
                Log.d(TAG,"mCallBack.onRegisterState start");
                if(mCallBack != null) {
                    Log.d(TAG, "mCallBack != null");
                    //mCallBack.onRegisterState(SipConst.REG_STATE_END);
                   String cause = getReason(msg_str);
                    Message m = Message.obtain(handler, MSG_TYPE.REG_STATE_END,cause);
                    m.sendToTarget();
                    Log.d(TAG, "mCallBack.onRegisterState end");
                }
            }
        }
        if(registrStates.equals(SipConst.REG_STATE_END)){
            if(mRegisterSequential != SipConst.REG_STATE_END){
                Message m = new Message();
                if(mNumber != null){
                    m.what = MSG_TYPE.HANGUP;
//                    hangup(mNumber);
//					Message hangupm = Message.obtain(handler, MSG_TYPE.HANGUP);
//					hangupm.sendToTarget();
                    handler.sendMessage(m);
                }else{
//                    handler.removeMessages(MSG_TYPE.REGISTER_START);
                    m.what = MSG_TYPE.TIMEOUT;
                    handler.sendMessage(m);

                }
                unregisterd();
//                if(mNumber != null){
////                    hangup(mNumber);
//                    Message hangupm = Message.obtain(handler, MSG_TYPE.HANGUP);
//                    hangupm.sendToTarget();
//                }
//                Log.d(TAG, "retry after " + mSipOption.getRegRetryInterval()/1000+" seconds");
//                Message m = Message.obtain(handler, MSG_TYPE.REG_STATE, SipConst.REG_STATE_START);
//                m.sendToTarget();
//                mCallBack.onRegisterState(SipConst.REG_STATE_START);

            }
        }
    }

    @Override
    public void notifyIncomingCall(MyCall myCall) {
        Log.d(TAG, "notifyIncomingCall");
        Message m = Message.obtain(handler, MSG_TYPE.INCOMING_CALL, myCall);
        m.sendToTarget();
    }

    @Override
    public void notifyCallState(MyCall myCall) {
        CallInfo ci;
        try {
            ci = myCall.getInfo();
        } catch (Exception e) {
            ci = null;
        }
        Message m = Message.obtain(handler, MSG_TYPE.CALL_STATE, ci);
        m.sendToTarget();
    }

    @Override
    public void notifyCallMediaState(MyCall myCall) {
        Message m = Message.obtain(handler, MSG_TYPE.CALL_MEDIA_STATE, null);
        m.sendToTarget();
    }

    @Override
    public void notifyBuddyState(MyBuddy myBuddy) {
        Message m = Message.obtain(handler, MSG_TYPE.BUDDY_STATE, myBuddy);
        m.sendToTarget();
    }

    @Override
    public void init(Context context){
        mContext = context;
        if (mPjSua2 == null) {
            Log.d(TAG, "3");
            mPjSua2 = new PjSua2();
            Log.d(TAG, "4");
            mPjSua2.init(JinglePhone.this, mContext.getFilesDir().getAbsolutePath());
        }
    }

    @Override
    public void register(RegisterParam param, ISipCallBack callback, SipOption options) {
        mCallBack = callback;
        mRegisterParam = param;
        mSipOption = options;

        if(mPjSua2 != null) {
            mRegisterSequential = SipConst.REG_STATE_START;
            Log.d(TAG, "1");
            mCallBack.onRegisterState(SipConst.REG_STATE_START, null);
            mRegisterStates = SipConst.REG_STATE_START;
//            if(ping(mRegisterParam.getIp())) {
            Log.d(TAG, "2");
            String username = mRegisterParam.getUsername();
            String ip = mRegisterParam.getIp();
            String password = mRegisterParam.getPassword();
            if (mPjSua2.accList.size() == 0) {
                Log.d(TAG, "3");
                mAccCfg = new AccountConfig();
                mAccCfg.setIdUri(SIP + username + AT + ip);
                mAccCfg.getRegConfig().setRegistrarUri(SIP + ip);
                mAccCfg.getNatConfig().setIceEnabled(true);
                mAccCfg.getVideoConfig().setAutoTransmitOutgoing(true);
                mAccCfg.getVideoConfig().setAutoShowIncoming(true);
                    mAccount = mPjSua2.addAcc(mAccCfg);
                } else {
                Log.d(TAG, "4");
                    mAccount = mPjSua2.accList.get(0);
                    mAccCfg = mAccount.cfg;
                }
                mBuddyList = new ArrayList<Map<String, String>>();
                for (int i = 0; i < mAccount.buddyList.size(); i++) {
                    mBuddyList.add(putData(mAccount.buddyList.get(i).cfg.getUri(),
                            mAccount.buddyList.get(i).getStatusText()));
                }
            Log.d(TAG, "5");
                    Log.d(TAG, "11-1");
            if (mAccCfg != null) {
                    AuthCredInfoVector creds = mAccCfg.getSipConfig().
                            getAuthCreds();
                    creds.clear();
                    Log.d(TAG, "11-2");
                    if (username.length() != 0) {
                        creds.add(new AuthCredInfo("Digest", "*", username, 0,
                                password));
                    }
                    Log.d(TAG, "mPjSua2.accList.size = "+mPjSua2.accList.size());
                    try {
                        Log.d(TAG, "11-3");
                        mAccount.modify(mAccCfg);
                    } catch (Exception e) {
                    }
            }else{

                mCallBack.onRegisterState(SipConst.REG_STATE_END,SipConst.REG_FAIL_IP_ABNORMAL);
//                Message m = new Message();
//                m.what = MSG_TYPE.REGISTER_START;
                unregisterd();
//                Log.d(TAG, "retry after " + mSipOption.getRegRetryInterval()/1000+" seconds");
//                handler.removeMessages(MSG_TYPE.REGISTER_START);
//                handler.sendMessageDelayed(m, mSipOption.getRegRetryInterval());
            }
//            }else{
//                mCallBack.onRegisterState(SipConst.REG_STATE_END);
//                Message m = new Message();
//                m.what = MSG_TYPE.REGISTER_START;
//                unregisterd();
//                Log.d(TAG, "retry after " + mSipOption.getRegRetryInterval()/1000+" seconds");
//                handler.sendMessageDelayed(m, mSipOption.getRegRetryInterval());
//            }
        }
    }

    @Override
    public void unregister() {
//        mPjSua2.deinit();
        if(mPjSua2 != null && mAccount != null) {

                mPjSua2.delAcc(mAccount);
            Log.d(TAG, "mPjSua2.accList.size = "+mPjSua2.accList.size());
//            mPjSua2.accList.remove(0);
//            mAccCfg.setIdUri("");
//            mAccCfg.getRegConfig().setRegistrarUri("");
//            AuthCredInfoVector creds = mAccCfg.getSipConfig().
//                    getAuthCreds();
//            creds.clear();
//            try {
//                mAccount.modify(mAccCfg);
//            } catch (Exception e) {}

            mAccount.delete();
        }
        mAccount = null;
        mAccCfg = null;
//        mMeCfg = null;
//        mCs = null;
//        mCallBack = null;
//        mRegisterParam = null;
//        mSipOption = null;
//        handler.removeMessages(MSG_TYPE.REGISTER_START);
        mRegisterSequential = SipConst.REG_STATE_END;
        mRegisterStates = SipConst.REG_STATE_END;
        mCallBack.onRegisterState(SipConst.REG_STATE_END,SipConst.REG_FAIL_MANUAL_STOP);
    }

    @Override
    public int makeCall(String number) {
        /* Only one call at anytime */
        MyCall currentCall = null;
        if (mCallMap.get(number) != null) {
            currentCall = mCallMap.get(number);
            if (currentCall != null) {
                return -1;
            }
        }
        if (mRegisterParam != null && mAccount != null) {
            String buddy_uri = SIP + number + AT + mRegisterParam.getIp();

            MyCall call = new MyCall(mAccount, -1);
            CallOpParam prm = new CallOpParam(true);

            try {
                Log.d(TAG, "buddy_uri = " + buddy_uri);
                mNumber = number;
                call.makeCall(buddy_uri, prm);
            } catch (Exception e) {
                call.delete();
                return -1;
            }
            currentCall = call;
            mCallMap.put(number, currentCall);
        }else{
            return -1;
        }
        CallState callState = new CallState();
        callState.setState(SipConst.CALL_STATE_CONNECTING);
        callState.setNumber(number);
        if(!mCallState.equals(SipConst.CALL_STATE_CONNECTING)) {
            mCallState = SipConst.CALL_STATE_CONNECTING;
            mCallBack.onCallState(callState);
        }
        return 0;
    }

    @Override
    public int answer(String number) {
        Log.d(TAG, "answer");
        CallOpParam prm = new CallOpParam();
        if (mCallMap.get(number) != null) {
            MyCall currentCall = mCallMap.get(number);
            if (currentCall != null) {
                Log.d(TAG, "currentCall != null");
                prm.setStatusCode(pjsip_status_code.PJSIP_SC_OK);
                try {
                    currentCall.answer(prm);
                } catch (Exception e) {
                    System.out.println(e);
                    return -1;
                }
            }else{
                return -1;
            }
        }else{
            return -1;
        }
        CallState callState = new CallState();
        callState.setState(SipConst.CALL_STATE_CONNECTING);
        callState.setNumber(number);
        if(!mCallState.equals(SipConst.CALL_STATE_CONNECTING)) {
            mCallState = SipConst.CALL_STATE_CONNECTING;
        mCallBack.onCallState(callState);
        }
        return 0;
    }

    @Override
    public int hangup(String number) {
        CallOpParam prm = new CallOpParam();
        if (mCallMap.get(number) != null) {
            MyCall currentCall = mCallMap.get(number);
            if (currentCall != null) {
                prm.setStatusCode(pjsip_status_code.PJSIP_SC_DECLINE);
                try {
                    Log.d(TAG, "currentCall.hangup = " + number);
                    currentCall.hangup(prm);
                    mNumber = null;
                } catch (Exception e) {
                    System.out.println(e);
                    return -1;
                }
            }else{
                return -1;
            }
        }else{
            return -1;
        }
        return 0;
    }

    @Override
    public int hold(String number) {
        CallOpParam prm = new CallOpParam();
        if (mCallMap.get(number) != null) {
            MyCall currentCall = mCallMap.get(number);
            if (currentCall != null) {
                prm.setOptions(2);
                try {
                    currentCall.setHold(prm);
                } catch (Exception e) {
                    System.out.println(e);
                    return -1;
                }
            }else{
                return -1;
            }
        }else{
            return -1;
        }
        return 0;
    }

    @Override
    public int unhold(String number) {
        CallOpParam prm = new CallOpParam();
        if (mCallMap.get(number) != null) {
            MyCall currentCall = mCallMap.get(number);
            if (currentCall != null) {
                Log.d(TAG, "currentCall != null");
                try {
                    mCs = currentCall.getInfo().getSetting();
                    if (mCs != null) {
                        Log.d(TAG, "mCs != null");
                        mCs.setFlag(1);
                        prm.setOpt(mCs);
                    }
                    currentCall.reinvite(prm);
                } catch (Exception e) {
                    System.out.println(e);
                    return -1;
                }
            }else{
                return -1;
            }
        }else{
            return -1;
        }
        return 0;
    }

    @Override
    public void echoCancel(boolean echoMode) {
        if (mMeCfg == null) {

            mMeCfg = new MediaConfig();
        }
        if (echoMode == true) {
            mMeCfg.setEcTailLen(200);
        } else {
            mMeCfg.setEcTailLen(0);
        }
        Log.d(TAG, "mMeCfg.getEcTailLen() = " + mMeCfg.getEcTailLen());
    }

    @Override
    public boolean handleMessage(final Message m) {
        if (m.what == 0) {

            mPjSua2.deinit();
            Runtime.getRuntime().gc();
            android.os.Process.killProcess(android.os.Process.myPid());

        } else {
            String log = "";
            if (m.what == MSG_TYPE.CALL_STATE) {
                Log.d(TAG, "m.what == MSG_TYPE.CALL_STATE");

                CallInfo ci = (CallInfo) m.obj;
                String call_state = "";
                if (mCallBack != null) {
                    String phonename = "";
                    String strm[] = ci.getRemoteUri().split("sip:");
                    String strm1[] = strm[1].split("@");
                    phonename = strm1[0].substring(0, strm1[0].length());
                    String callCodec = "";
                    if (ci.getState().swigValue() < pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED
                            .swigValue()) {
                        Log.d("call",
                                "ci.getState().swigValue() < pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED.swigValue()");
                        Log.d("call",
                                "ci.getStateText() = "+ci.getStateText());
//                        if(ci.getLastStatusCode() != null){
//                            Log.d("call",
//                                    "ci.getLastStatusCode() = "+ci.getLastStatusCode().toString());
//                        }
                        if(ci.getStateText().equals("CALLING")){
                            call_state = SipConst.CALL_STATE_CALLING;

                        }else if (ci.getStateText().equals("EARLY")){
                            call_state = SipConst.CALL_STATE_REMOTE_RINGING;
                        }

                    } else if (ci.getState().swigValue() >= pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED
                            .swigValue()) {
//                        call_state = ci.getStateText();
                        Log.d("call",
                                "ci.getStateText() = "+ci.getStateText());
//                        if(ci.getLastStatusCode() != null){
//                            Log.d("call",
//                                    "ci.getLastStatusCode() = "+ci.getLastStatusCode());
//                        }
                        if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED) {

                            Log.d("call",
                                    "ci.getRole() == pjsip_role_e.PJSIP_INV_STATE_CONFIRMED");
                            if (mCs != null) {
                                mCs = ci.getSetting();
                            }
                                CallMediaInfoVector cmiv = ci.getMedia();
                                if(cmiv != null) {
                                    for (long i = 0; i < cmiv.size(); i++) {
                                        try {
                                            StreamInfo strinfo = mCallMap.get(phonename).getStreamInfo(i);
                                            Log.d(TAG, "strinfo.getCodecName = " + strinfo.getCodecName());
                                            callCodec = strinfo.getCodecName();
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                    }
                                }
                            }
                            call_state = SipConst.CALL_STATE_REMOTE_ANSWER;
                        } else if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) {
                            Log.d("call",
                                    "ci.getRole() == pjsip_role_e.PJSIP_INV_STATE_DISCONNECTED");
                            if (ci.getLastReason().equals(
                                    JinglePhoneDef.STATE_DECLINE)){
                                log = "200";
                            }else if(ci.getLastReason()
                                    .equals(JinglePhoneDef.STATE_NORMALCALLCLEARING)){
                                log = "503";
                            }else if (ci.getLastReason().equals(
                                    JinglePhoneDef.STATE_TIMEOUT)) {
                                log = "408";
                            } else {
                                log = "480";
                            }
//                            Log.d(TAG,"getStateText = "+ci.getStateText());
                            call_state = SipConst.CALL_STATE_REMOTE_HANG;
                        }
                    }

                    if (!call_state.equals("")) {
                        Log.d("call", "call_state = " + call_state);
                        if (call_state.equals(SipConst.CALL_STATE_CALLING)||
                                call_state.equals(SipConst.CALL_STATE_CONNECTING)||
                                call_state.equals(SipConst.CALL_STATE_REMOTE_RINGING)
                                || call_state
                                .equals(SipConst.CALL_STATE_REMOTE_HANG)
                                || call_state.equals(SipConst.CALL_STATE_REMOTE_ANSWER)) {
                            CallState callState = new CallState();
                            callState.setState(call_state);
                            callState.setNumber(phonename);
                            callState.setCodec(callCodec);
                            if(!log.equals("")){
                                Log.d(TAG,"log = "+ log);
                                callState.setExtra(log);
                            }
                            if(!mCallState.equals(call_state)) {
                                mCallState = call_state;
                            mCallBack.onCallState(callState);
                            }
//                            if(call_state.equals(SipConst.CALL_STATE_REMOTE_ANSWER)){
//                                Log.d(TAG, "mSipOption.getChkIntervalInCall1 = " + mSipOption.getChkIntervalInCall());
//                                if(mSipOption.getChkIntervalInCall() != 0){
//                                    Log.d(TAG, "mSipOption.getChkIntervalInCall = " + mSipOption.getChkIntervalInCall());
//                                    Message msg = new Message();
//                                    msg.what = MSG_TYPE.ANSWER_CHECK;
//                                    msg.obj = phonename;
//                                    mAnswerCheckCount = 0;
//                                    handler.sendMessageDelayed(msg,mSipOption.getChkIntervalInCall());
//                                }
//                            }
                            if (call_state.equals(SipConst.CALL_STATE_REMOTE_HANG)) {
//                                handler.removeMessages(MSG_TYPE.ANSWER_CHECK);
                                mNumber = null;
                                mCallMap.remove(phonename);

                            }

                        }
                    }

                }

            } else if (m.what == MSG_TYPE.CALL_MEDIA_STATE) {
                Log.d("call", "m.what == MSG_TYPE.CALL_MEDIA_STATE");
            } else if (m.what == MSG_TYPE.BUDDY_STATE) {
                Log.d("call", "m.what == MSG_TYPE.BUDDY_STATE");
                MyBuddy buddy = (MyBuddy) m.obj;
                int idx = mAccount.buddyList.indexOf(buddy);

			/*
			 * Update buddy status text, if buddy is valid and the buddy lists
			 * in account and UI are sync-ed.
			 */
                if (idx >= 0 && mAccount.buddyList.size() == mBuddyList.size()) {
                    mBuddyList.get(idx).put("status", buddy.getStatusText());
                    mBuddyListAdapter.notifyDataSetChanged();

				/* Return back Call activity */
                    // notifyCallState(currentCall);
                }

            } else if (m.what == MSG_TYPE.REG_STATE) {
                String msg = (String)m.obj;
                mCallBack.onRegisterState(msg,null);

            } else if (m.what == MSG_TYPE.REG_STATE_END) {
                String msg = (String)m.obj;
                mCallBack.onRegisterState(SipConst.REG_STATE_END,msg);

            } else if (m.what == MSG_TYPE.INCOMING_CALL) {

			/* Incoming call */
                final MyCall call = (MyCall) m.obj;
                CallOpParam prm = new CallOpParam();
                String phonename = "";
                try {
                    Log.d(TAG, "uri = " + call.getInfo().getRemoteUri());
                    String strm[] = call.getInfo().getRemoteUri().split("sip:");
                    String strm1[] = strm[1].split("@");
                    Log.d(TAG, "strm[1] = " + strm[1]);
                    phonename = strm1[0].substring(0, strm1[0].length());
                    MyCall currentCall;
                    if (mCallMap.get(phonename) != null) {
                        currentCall = mCallMap.get(phonename);

					/* Only one call at anytime */
                        if (currentCall != null) {
						/*
						 * prm.setStatusCode(pjsip_status_code.PJSIP_SC_BUSY_HERE
						 * ); try { call.hangup(prm); } catch (Exception e) {}
						 */
                            // TODO: set status code
                            call.delete();
                            return true;
                        }
                    }
				/* Answer with ringing */
                    prm.setStatusCode(pjsip_status_code.PJSIP_SC_RINGING);
                    try {
                        call.answer(prm);
                    } catch (Exception e) {
                    }

                    currentCall = call;
                    if (mCallBack != null) {
                        CallMediaInfoVector cmiv = call.getInfo().getMedia();
                        String callCodec = "";
                        if(cmiv != null) {
                            for (long i = 0; i < cmiv.size(); i++) {
                                try {
                                    StreamInfo strinfo = call.getStreamInfo(i);
                                    Log.d(TAG, "strinfo.getCodecName = " + strinfo.getCodecName());
                                    callCodec = strinfo.getCodecName();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                        CallState callState = new CallState();
                        callState.setNumber(phonename);
                        callState.setState(SipConst.CALL_STATE_INCOMING);
                        callState.setCodec(callCodec);
                        mCallMap.put(phonename, currentCall);
                        if(!mCallState.equals(SipConst.CALL_STATE_INCOMING)) {
                            mCallState = SipConst.CALL_STATE_INCOMING;
                        mCallBack.onCallState(callState);
                    }
                    }
                } catch (Exception e) {
                    System.out.println(e);
                }

            }else if(m.what == MSG_TYPE.REGISTER_START) {
//                RegisterParam param = mRegisterParam;
//                SipOption options = mSipOption;
//                Log.d(TAG,"MSG_TYPE.REGISTER_START");
//                register(param,mCallBack,options);
            }else if(m.what == MSG_TYPE.TDMF_STATE) {
                mCallBack.onReceiveDTMF((String)m.obj);
//            } else if (m.what == MSG_TYPE.ANSWER_CHECK) {
//                final String number = (String) m.obj;
//                Log.d("call", "ANSWER_CHECK number = " + number);
//                new Thread(new Runnable() {
//                    public void run() {
//                        if (ping(mRegisterParam.getIp()) == false) {
//                            Log.d(TAG, "mAnswerCheckCount = " + mAnswerCheckCount);
//                            mAnswerCheckCount++;
//                            if (mAnswerCheckCount >= mSipOption.getMaxChkFailCountInCall()) {
//                                hangup(number);
//                            } else {
//                                Message msg = new Message();
//                                msg.what = MSG_TYPE.ANSWER_CHECK;
//                                msg.obj = number;
//                                handler.sendMessageDelayed(msg, mSipOption.getChkIntervalInCall());
//                            }
//                        } else {
//                            Message msg = new Message();
//                            msg.what = MSG_TYPE.ANSWER_CHECK;
//                            msg.obj = number;
//                            handler.sendMessageDelayed(msg, mSipOption.getChkIntervalInCall());
//                        }
//                    }
//                }).start();
            }else if (m.what == MSG_TYPE.HANGUP){
                Log.d(TAG, " MSG_TYPE.HANGUP = " + mNumber);
                hangup(mNumber);
//                Message mg = new Message();
//                mg.what = MSG_TYPE.REGISTER_START;
//                handler.sendMessageDelayed(mg, mSipOption.getRegRetryInterval());
            }else if(m.what == MSG_TYPE.TIMEOUT) {
//                Message mg = new Message();
//                mg.what = MSG_TYPE.REGISTER_START;
//                handler.sendMessageDelayed(mg, mSipOption.getRegRetryInterval());
            }else {
			/* Message not handled */
                return false;

            }
        }

        return true;
    }

    private HashMap<String, String> putData(String uri, String status) {
        HashMap<String, String> item = new HashMap<String, String>();
        item.put("uri", uri);
        item.put("status", status);
        return item;
    }

    private static final boolean ping(String ip) {

        try {
            Log.d(TAG, "ip= "+ip);
            Process p = Runtime.getRuntime().exec("ping -c 3 -w 100 " + ip);
// PING的状态

            int status = p.waitFor();

            if (status == 0) {

                return true;

            }

        } catch (IOException e) {

        } catch (InterruptedException e) {

        } finally {

        }

        return false;

    }
    private void unregisterd(){
        if(mPjSua2 != null && mAccount != null) {
            mPjSua2.delAcc(mAccount);
            Log.d(TAG, "mPjSua2.accList.size = "+mPjSua2.accList.size());
            mAccount.delete();
        }
        mAccount = null;
        mAccCfg = null;
    }

    String getReason(String msg_str){
        String rtn = "";
        if(msg_str == null){
            return rtn;
        }
        if(msg_str.equals("Registration failed: gethostbyname() has returned error (PJ_ERESOLVE)")){
            rtn = SipConst.REG_FAIL_IP_ABNORMAL;
        }else if(msg_str.equals("Registration failed: Forbidden")){
            rtn = SipConst.REG_FAIL_INVALID_USER;
        }else if(msg_str.equals("Registration failed: Unauthorized")){
            rtn = SipConst.REG_FAIL_WRONG_PASSWORD;
        }else if(msg_str.equals("Registration failed: Network is unreachable")){
            rtn = SipConst.REG_FAIL_NO_NETWORK;
        }else{
            rtn = SipConst.REG_FAIL_CONNECTION_TIMEOUT;
        }
        return rtn;
    }
}
